package com.android.delivery

import android.content.Context
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.util.Log
import com.ada.common.util.GsonUtil
import com.alibaba.sdk.android.push.CommonCallback
import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory
import com.android.delivery.base.BaseApplication
import com.android.delivery.constant.Constants
import com.android.delivery.entity.LoginInfo
import com.blankj.utilcode.util.SPUtils
import com.bolex.autoEx.AutoEx
import com.lzy.okgo.OkGo
import com.lzy.okgo.cache.CacheEntity
import com.lzy.okgo.cookie.CookieJarImpl
import com.lzy.okgo.cookie.store.DBCookieStore
import com.lzy.okgo.https.HttpsUtils
import com.lzy.okgo.interceptor.HttpLoggingInterceptor
import com.scwang.smart.refresh.footer.ClassicsFooter
import com.scwang.smart.refresh.header.ClassicsHeader
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import com.scwang.smart.refresh.layout.api.RefreshFooter
import com.scwang.smart.refresh.layout.api.RefreshLayout
import com.scwang.smart.refresh.layout.listener.DefaultRefreshFooterCreator
import com.squareup.leakcanary.LeakCanary
import com.tencent.map.geolocation.TencentLocationRequest
import com.uuzuche.lib_zxing.activity.ZXingLibrary
import okhttp3.OkHttpClient
import java.util.concurrent.TimeUnit
import java.util.logging.Level


class App : BaseApplication() {
    /**
     * 全局定义，用于定位请求
     */
    private var mLoginInfo: LoginInfo? = null

    companion object {
        private lateinit var sInstance: App

        init {
            SmartRefreshLayout.setDefaultRefreshHeaderCreator { context, layout ->
                layout.setPrimaryColorsId(R.color.colorPrimary, R.color.colorTextNormal) //全局设置主题颜色
                val classicsHeader = ClassicsHeader(context)
                classicsHeader.setBackgroundResource(R.color.bgColor)
                classicsHeader //.setTimeFormat(new DynamicTimeFormat("更新于 %s"));//指定为经典Header，默认是 贝塞尔雷达Header
            }
            //设置全局的Footer构建器
            //设置全局的Footer构建器
            SmartRefreshLayout.setDefaultRefreshFooterCreator(object : DefaultRefreshFooterCreator {
                override fun createRefreshFooter(context: Context, layout: RefreshLayout): RefreshFooter {
                    return ClassicsFooter(context).setDrawableSize(20f)
                }
            })
        }

        /**获取应用的application实例 */
        open fun getInstance(): App? {
            return sInstance
        }
    }

    override fun onCreate() {
        sInstance = this
        super.onCreate()
    }

    override fun init() {
        AutoEx.apply() //一行即可
        if (LeakCanary.isInAnalyzerProcess(this)) {
            // This process is dedicated to LeakCanary for heap analysis.
            // You should not init your app in this process.
            return;
        }
        LeakCanary.install(this);

        initOkGo()

        ZXingLibrary.initDisplayOpinion(this);

        registerPush(this)
    }

    private val DEFAULT = 2
    private val LEVELS = intArrayOf(
            TencentLocationRequest.REQUEST_LEVEL_GEO,
            TencentLocationRequest.REQUEST_LEVEL_NAME,
            TencentLocationRequest.REQUEST_LEVEL_ADMIN_AREA,
            TencentLocationRequest.REQUEST_LEVEL_POI)
    private val mLevel: Int = LEVELS.get(DEFAULT)

    private fun initOkGo() {

        //---------这里给出的是示例代码,告诉你可以这么传,实际使用的时候,根据需要传,不需要就不传-------------//
        //---------这里给出的是示例代码,告诉你可以这么传,实际使用的时候,根据需要传,不需要就不传-------------//
//        val headers = HttpHeaders()
//        headers.put(AUTHORIZATION, BEARER + SPUtils.getInstance().getString(SputilsConstant.TOKEN)) //header不支持中文，不允许有特殊字符

        val builder = OkHttpClient.Builder()
        //log相关
        //log相关
        val loggingInterceptor = HttpLoggingInterceptor("OkGo")
        loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY) //log打印级别，决定了log显示的详细程度

        loggingInterceptor.setColorLevel(Level.INFO) //log颜色级别，决定了log在控制台显示的颜色

        builder.addInterceptor(loggingInterceptor) //添加OkGo默认debug日志

        //第三方的开源库，使用通知显示当前请求的log，不过在做文件下载的时候，这个库好像有问题，对文件判断不准确
        //builder.addInterceptor(new ChuckInterceptor(this));

        //超时时间设置，默认60秒
        //第三方的开源库，使用通知显示当前请求的log，不过在做文件下载的时候，这个库好像有问题，对文件判断不准确
        //builder.addInterceptor(new ChuckInterceptor(this));

        //超时时间设置，默认60秒
        builder.readTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS) //全局的读取超时时间

        builder.writeTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS) //全局的写入超时时间

        builder.connectTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS) //全局的连接超时时间


        //自动管理cookie（或者叫session的保持），以下几种任选其一就行
//        builder.cookieJar(new CookieJarImpl(new SPCookieStore(this)));            //使用sp保持cookie，如果cookie不过期，则一直有效

        //自动管理cookie（或者叫session的保持），以下几种任选其一就行
//        builder.cookieJar(new CookieJarImpl(new SPCookieStore(this)));            //使用sp保持cookie，如果cookie不过期，则一直有效
        builder.cookieJar(CookieJarImpl(DBCookieStore(this))) //使用数据库保持cookie，如果cookie不过期，则一直有效

        //builder.cookieJar(new CookieJarImpl(new MemoryCookieStore()));            //使用内存保持cookie，app退出后，cookie消失

        //https相关设置，以下几种方案根据需要自己设置
        //方法一：信任所有证书,不安全有风险
        //builder.cookieJar(new CookieJarImpl(new MemoryCookieStore()));            //使用内存保持cookie，app退出后，cookie消失

        //https相关设置，以下几种方案根据需要自己设置
        //方法一：信任所有证书,不安全有风险
        val sslParams1 = HttpsUtils.getSslSocketFactory()
        builder.sslSocketFactory(sslParams1.sSLSocketFactory, sslParams1.trustManager)
//        //配置https的域名匹配规则，详细看demo的初始化介绍，不需要就不要加入，使用不当会导致https握手失败
//        builder.hostnameVerifier(new SafeHostnameVerifier());

        // 其他统一的配置
        // 详细说明看GitHub文档：https://github.com/jeasonlzy/
        //        //配置https的域名匹配规则，详细看demo的初始化介绍，不需要就不要加入，使用不当会导致https握手失败
//        builder.hostnameVerifier(new SafeHostnameVerifier());

        // 其他统一的配置
        // 详细说明看GitHub文档：https://github.com/jeasonlzy/
        OkGo.getInstance().init(this) //必须调用初始化
                .setOkHttpClient(builder.build()) //建议设置OkHttpClient，不设置会使用默认的
                //                .setCacheMode(CacheMode.NO_CACHE)               //全局统一缓存模式，默认不使用缓存，可以不传
//                .addCommonHeaders(headers)              //全局公共头
                .setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE).retryCount = 3 //全局统一超时重连次数，默认为三次，那么最差的情况会请求4次(一次原始请求，三次重连请求)，不需要可以设置为0


//                .addCommonParams(params);                       //全局公共参数
    }

    fun setLoginInfo(loginInfo: LoginInfo) {
        mLoginInfo = loginInfo
        SPUtils.getInstance().put(Constants.LOGIN_INFO, GsonUtil.toJson(loginInfo))
    }

    fun clearLoginInfo() {
        mLoginInfo = null
        SPUtils.getInstance().put(Constants.LOGIN_INFO, "")
    }

    fun getLoginInfo(): LoginInfo? {
        if (mLoginInfo == null) {
            val loginInfoStr = SPUtils.getInstance().getString(Constants.LOGIN_INFO)
            mLoginInfo = GsonUtil.parse(loginInfoStr, LoginInfo::class.java)
        }
        return mLoginInfo
    }

    /**
     * 获取版本号
     *
     * @return
     */
    fun getAppVersionCode(): Int {
        return try {
            val mPackageManager: PackageManager = getPackageManager()
            val _info: PackageInfo = mPackageManager.getPackageInfo(getPackageName(), 0)
            _info.versionCode
        } catch (e: PackageManager.NameNotFoundException) {
            0
        }
    }

    /**
     * 建立推送通道
     */
    fun registerPush(context: Context) {
        PushServiceFactory.init(context)
        val pushService = PushServiceFactory.getCloudPushService()
        pushService.register(context, object : CommonCallback {
            override fun onSuccess(response: String) {
                Log.e("registerPush onSuccess", "deviceId:")
            }

            override fun onFailed(errorCode: String, errorMessage: String) {
                Log.e("registerPush onFailed", errorMessage)
            }

        })
    }
}